package com.code2roc.jarmanage.depoly;

import com.code2roc.jarmanage.db.ConfigDB;
import com.code2roc.jarmanage.model.ConfigDO;
import com.code2roc.jarmanage.model.ProjectDO;
import com.code2roc.jarmanage.util.*;
import org.dom4j.Element;

import java.io.*;
import java.util.Arrays;
import java.util.List;

public class LinuxDepolyService implements DepolyService {
    @Override
    public void install(ProjectDO entity) {
        ConfigDO configDO = ConfigDB.selectOne("JAVA_HOME");
        String javaHomePath = EnviromentUtil.getJavaHome();
        if (configDO == null) {
            configDO = new ConfigDO();
            configDO.setConfigID("JAVA_HOME");
            configDO.setConfigValue(javaHomePath);
            ConfigDB.insert(configDO);
        } else {
            configDO.setConfigValue(javaHomePath);
            ConfigDB.update(configDO);
        }
        saveConfig(entity);
    }

    @Override
    public void unInstall(ProjectDO entity) {
        String command = "systemctl reset-failed";
        CMDUtil.executeLinuxCommand(command);
        command = "systemctl disable " + entity.getServiceName();
        CMDUtil.executeLinuxCommand(command);
        String depolyFilePath = entity.getJarPackagePath() + File.separator + entity.getServiceName() + ".sh";
        File depolyFile = new File(depolyFilePath);
        depolyFile.delete();
        String depolyStartFilePath = File.separator + "etc" + File.separator + "systemd" + File.separator + "system" + File.separator + entity.getServiceName() + "start.sh";
        File depolyStartFile = new File(depolyStartFilePath);
        depolyStartFile.delete();
        String depolyStopFilePath = File.separator + "etc" + File.separator + "systemd" + File.separator + "system" + File.separator + entity.getServiceName() + "stop.sh";
        File depolyStopFile = new File(depolyStopFilePath);
        depolyStopFile.delete();
        String depolyServiceFilePath = File.separator + "etc" + File.separator + "systemd" + File.separator + "system" + File.separator + entity.getServiceName() + ".service";
        File depolyServiceFile = new File(depolyServiceFilePath);
        depolyServiceFile.delete();
        command = "systemctl daemon-reload";
        CMDUtil.executeLinuxCommand(command);
    }

    @Override
    public void start(ProjectDO entity) {
        String command = "chmod u+x " + entity.getServiceName() + ".sh";
        CMDUtil.executeLinuxCommand(command);
        command = "systemctl reset-failed";
        CMDUtil.executeLinuxCommand(command);
        command = "systemctl start " + entity.getServiceName();
        CMDUtil.executeLinuxCommand(command);
    }

    @Override
    public void stop(ProjectDO entity) {
        String command = "systemctl stop " + entity.getServiceName();
        CMDUtil.executeLinuxCommand(command);
    }

    @Override
    public String getStatus(String serviceName) {
        String status = DepolyStatus.UnInstall;
        try {
            String command = "systemctl status " + serviceName;
            String commandResultFilePath = CMDUtil.executeLinuxCommandWithStore(command);
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(commandResultFilePath)));
            String line = reader.readLine();
            while (line != null) {
                if (line.trim().startsWith("Active")) {
                    if (line.trim().indexOf("inactive (dead)") > 0)
                        status = DepolyStatus.Stopped;
                    else if (line.trim().indexOf("active (running)") > 0)
                        status = DepolyStatus.Running;
                    else if (line.trim().indexOf("failed") > 0)
                        status = DepolyStatus.Stopped;
                }
                line = reader.readLine();
            }
        } catch (IOException e) {
            LogUtil.error(e);
        }
        return status;
    }

    private void saveConfig(ProjectDO entity) {
        initDepolyFile(entity);
        initDepolyStartFile(entity);
        initDepolyStopFile(entity);
        initDepolyServiceFile(entity);
        String command = "systemctl reset-failed";
        CMDUtil.executeLinuxCommand(command);
        command = "systemctl enable " + entity.getServiceName();
        CMDUtil.executeLinuxCommand(command);
    }

    private void initDepolyFile(ProjectDO entity) {
        ConfigDO configDO = ConfigDB.selectOne("JAVA_HOME");
        String javaHome = configDO.getConfigValue();
        if(!StringUtil.isEmpty(entity.getJavaHome())){
            javaHome = entity.getJavaHome();
        }
        String depolyFilePath = entity.getJarPackagePath() + File.separator + entity.getServiceName() + ".sh";
        File depolyFile = new File(depolyFilePath);
        depolyFile.delete();
        FileUtil.copyFile("resources" + File.separator + "linux" + File.separator + "deploy.sh", depolyFilePath);
        String fileContent = FileUtil.readFileContentKeepLine(depolyFilePath);
        fileContent = fileContent.replace("[JAVA_HOME]", javaHome);
        fileContent = fileContent.replace("[serviceName]", entity.getServiceName());
        fileContent = fileContent.replace("[jarPackagePath]", new File(entity.getJarPackagePath()).getAbsolutePath());
        fileContent = fileContent.replace("[depolyBeforeParam]", entity.getDepolyBeforeParam());
        fileContent = fileContent.replace("[depolyAfterParam]", entity.getDepolyAfterParam());
        if(!StringUtil.isEmpty(entity.getDepolyPort())){
            fileContent = fileContent.replace("[depolyPort]", "--server.port="+entity.getDepolyPort());

        }else{
            fileContent = fileContent.replace("[depolyPort]", "");
        }
        FileUtil.writeFile(depolyFilePath, fileContent, false);
    }

    private void initDepolyStartFile(ProjectDO entity) {
        String depolyStartFilePath = File.separator + "etc" + File.separator + "systemd" + File.separator + "system" + File.separator + entity.getServiceName() + "start.sh";
        File depolyStartFile = new File(depolyStartFilePath);
        depolyStartFile.delete();
        FileUtil.copyFile("resources" + File.separator + "linux" + File.separator + "deploystart.sh", depolyStartFilePath);
        String fileContent = FileUtil.readFileContentKeepLine(depolyStartFilePath);
        fileContent = fileContent.replace("[serviceName]", entity.getServiceName());
        fileContent = fileContent.replace("[jarPackagePath]", new File(entity.getJarPackagePath()).getAbsolutePath());
        FileUtil.writeFile(depolyStartFilePath, fileContent, false);
    }

    private void initDepolyStopFile(ProjectDO entity) {
        String depolyStopFilePath = File.separator + "etc" + File.separator + "systemd" + File.separator + "system" + File.separator + entity.getServiceName() + "stop.sh";
        File depolyStopFile = new File(depolyStopFilePath);
        depolyStopFile.delete();
        FileUtil.copyFile("resources" + File.separator + "linux" + File.separator + "deploystop.sh", depolyStopFilePath);
        String fileContent = FileUtil.readFileContentKeepLine(depolyStopFilePath);
        fileContent = fileContent.replace("[serviceName]", entity.getServiceName());
        fileContent = fileContent.replace("[jarPackagePath]", new File(entity.getJarPackagePath()).getAbsolutePath());
        FileUtil.writeFile(depolyStopFilePath, fileContent, false);
    }

    private void initDepolyServiceFile(ProjectDO entity) {
        String depolyServiceFilePath = File.separator + "etc" + File.separator + "systemd" + File.separator + "system" + File.separator + entity.getServiceName() + ".service";
        File depolyServiceFile = new File(depolyServiceFilePath);
        depolyServiceFile.delete();
        FileUtil.copyFile("resources" + File.separator + "linux" + File.separator + "deploy.service", depolyServiceFilePath);
        String fileContent = FileUtil.readFileContentKeepLine(depolyServiceFilePath);
        fileContent = fileContent.replace("[serviceName]", entity.getServiceName());
        if (!StringUtil.isEmpty(entity.getDependService())) {
            List<String> serviceList = Arrays.asList(entity.getDependService().split("\\|"));
            String depolyAfter = "";
            for (String service : serviceList) {
                depolyAfter += "After=" + service + ".service" + System.getProperty("line.separator");
            }
            fileContent = fileContent.replace("[depolyAfter]", depolyAfter);
        } else {
            fileContent = fileContent.replace("[depolyAfter]", "");
        }
        FileUtil.writeFile(depolyServiceFilePath, fileContent, false);
        String serviceLogPath = entity.getJarPackagePath() + File.separator + "deploylog";
        File logDir = new File(serviceLogPath);
        if (!logDir.exists()) {
            logDir.mkdirs();
        }
    }
}
